package com.zhijian.warehouse.manage.aop;

import com.zhijian.autoconfigure.cache.CacheClient;
import com.zhijian.util.JsonUtil;
import com.zhijian.util.token.TokenBean;
import com.zhijian.util.token.TokenUtil;
import com.zhijian.warehouse.manage.config.Constants;
import com.zhijian.warehouse.manage.entity.dto.UserDto;
import com.zhijian.warehouse.manage.entity.po.User;
import com.zhijian.warehouse.manage.enums.ResponseEnum;
import com.zhijian.warehouse.manage.enums.SystemEnum;
import com.zhijian.warehouse.manage.exception.BusinessCommonException;
import com.zhijian.warehouse.manage.holder.CurrentH5UserHolder;
import com.zhijian.warehouse.manage.service.TokenService;
import com.zhijian.warehouse.manage.service.UserService;
import com.zhijian.warehouse.manage.util.AssertCommonUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Objects;


/**
 * 登陆拦截
 *
 * @Author hcg
 * @Date 2022年6月2
 * @Version 1.0.1
 */
@Slf4j
public class H5LoginInterceptor implements HandlerInterceptor {

    private CacheClient cacheClient;

    private UserService userService;

    private TokenService tokenService;

    public H5LoginInterceptor() {
    }

    public H5LoginInterceptor(CacheClient cacheClient, UserService userService, TokenService tokenService) {
        this.cacheClient = cacheClient;
        this.userService = userService;
        this.tokenService = tokenService;
    }

    /**
     * 拦截请求，校验token
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        String token = request.getHeader(SystemEnum.H5.getTokenKey());
        if (StringUtils.isBlank(token)) {
            log.warn("【H5WebLoginInterceptor】 error,the parameter '{}' is empty", SystemEnum.H5.getTokenKey());
            log.warn("the request path is {}", request.getRequestURI());
            AssertCommonUtil.notNull(token, ResponseEnum.ERROR_AUTH_LOGIN);
            throw new BusinessCommonException(ResponseEnum.ERROR_AUTH_LOGIN);
        }
        //根据token获取创建时的用户信息
        UserDto user = tokenService.getUserDtoByToken(SystemEnum.H5, token);
        if (Objects.isNull(user)) {
            log.warn("【H5WebLoginInterceptor】 error,can not get user by token {}", token);
            log.warn("the request path is {}", request.getRequestURI());
            AssertCommonUtil.notNull(user, ResponseEnum.ERROR_AUTH_LOGIN);
        }
        User u = userService.selectById(user.getId());
        if (Objects.isNull(u)) {
            //每次都查下
            log.warn("【H5WebLoginInterceptor】 error, the user is not exist, the id is {}", user.getId());
            log.warn("the request path is {}", request.getRequestURI());
            AssertCommonUtil.notNull(u, ResponseEnum.ERROR_AUTH_LOGIN);
        }
        //校验用户token状态
        //token版本号
        String tokenVersion = "1.0";
        TokenBean tokenBean = new TokenBean(Constants.TOKEN_ACCESS_KEY, Constants.TOKEN_SECRET_KEY, tokenVersion, "login", "POST", null, JsonUtil.toString(user));
        if (!TokenUtil.validateToken(token, tokenBean, true)) {
            log.error("【AppLoginInterceptor】 error,token valid false, {}", token);
            AssertCommonUtil.notNull(null, ResponseEnum.ERROR_AUTH_LOGIN);
        }
        //延长时间
        cacheClient.setExSeconds(String.format(Constants.Redis.H5_USER_LOGIN_TOKEN, user.getPhone(), user.getSort()), token, SystemEnum.H5.getLoginExpireTime());
        //缓存生成token的用户信息
        cacheClient.setExSeconds(String.format(Constants.Redis.H5_TOKEN_LOGIN_USER, token), JsonUtil.toString(user), SystemEnum.H5.getLoginExpireTime());
        CurrentH5UserHolder.setUser(user);
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        CurrentH5UserHolder.clear();
    }
}
